
AddCSLuaFile( "autorun/client/st_client.lua" )
AddCSLuaFile( "sky_titans/shared/st_spawntool_list.lua" )
AddCSLuaFile( "sky_titans/shared/st_weapons.lua" )
AddCSLuaFile( "sky_titans/shared/st_ammo.lua" )

cvar_ff = CreateConVar("st_friendlyfire", "0")

//list of entities that ST weapons can damage
candamage = {"prop_physics","st_boiler","st_weapon","st_fan","st_balloon"}

//Calculates the health of entities
function CalcHealth( ent )
if(ent:IsValid()) then
local phys = ent:GetPhysicsObject()
	if( phys:IsValid() and !string.find(ent:GetClass(),"hoverball")) then
		return math.ceil( (math.pow(phys:GetVolume(),0.45)/2) * (0.2 + math.sqrt(phys:GetMass()/math.sqrt(50000))*0.8 ) /5 )*5
	else
		return 0
	end
end
end

//Gets a 0-1 value from a value between 2 other values
function RangeScale(n,min,max,clamp)
    if(clamp==true) then return math.Clamp( (max-n)/(max-min) ,0,1) else return (max-n)/(max-min) end
end

//Costs the player a certain amount of money, returning false if they don't have enough
function CostMoney( ply, amount )
    local nextmoney = ply:GetNetworkedInt("st_money")
    local nextmoneyhold = ply:GetNetworkedInt("st_moneyhold")
    if(nextmoney+nextmoneyhold>=amount) then
        ply:SetNetworkedInt("st_moneyhold",nextmoneyhold - amount)
        return true
    else
        return false
    end
end

//Specific to the spawnable entities, checks their owner, price, and repay automatically
function Ent_InitCost( ent )
    if(ent.Owner and ent.Owner:IsValid()) then
        local spawnclass = ent:GetClass()
        local ply = ent.Owner
        if( CostMoney(ply,ent.cost)==false or ply:CheckLimit("_"..spawnclass)==false ) then
            ent.Repay = 0
            ent:Remove()
            return false
        else
            ply:AddCount( "_"..spawnclass, ent)
            ply:AddCleanup( spawnclass, ent )
        end
    end
end

//Returns the player's money when the entity has been removed. Usually wont be run if the entity was killed in combat.
function RemoveRepay( ent )
    if(ent.Owner:IsValid()) then
        if(ent.Repay==1) then
            local mult = ent.hp/ent.maxhp
            if(ent.Core and ent.Core:IsValid()) then mult = ent.Core.hp/ent.Core.maxhp end
            ent.Owner:SetNetworkedInt("st_moneyhold",ent.Owner:GetNetworkedInt("st_moneyhold") + ent.cost)
            ent.Owner:SetNetworkedInt("st_money", ent.Owner:GetNetworkedInt("st_money") - math.floor(ent.cost*(1-mult)) )
        else
            ent.Owner:SetNetworkedInt("st_moneyhold",ent.Owner:GetNetworkedInt("st_moneyhold") + ent.cost)
            ent.Owner:SetNetworkedInt("st_money", ent.Owner:GetNetworkedInt("st_money") - math.floor(ent.cost*(1-ent.Repay)) )
        end
    end
end

//Calculate the relative weakness of a specific entity to a specific damage type
function CalcWeakness( ent, dmgtype )
    local class = ent:GetClass()
    local mult = 1
    
    if(dmgtype=="pierce") then
        if(class=="st_balloon") then
            mult = 1.15
            ent.repair = ent.repair*0.85
        elseif(class=="prop_physics") then
            mult = 1.3
        elseif(class=="st_weapon" or class=="st_fan") then
            mult = 0.75
            ent.repair = ent.repair*0.9
        end
    end
    if(dmgtype=="explosive") then
        if(class=="st_weapon" or class=="st_fan") then
            mult = 1.25
            ent.repair = ent.repair*0.75
        elseif(class=="prop_physics") then
            mult = 0.75
        elseif(class=="st_balloon") then
            mult = 0.25
            ent.repair = ent.repair*0.95
        end
    end 
    if(dmgtype=="pellet") then
        if(class=="st_balloon") then
            mult = 1.6
            ent.repair = ent.repair*0.8
        elseif(class=="prop_physics") then
            mult = 0.25
        elseif(class=="st_weapon" or class=="st_fan") then
            mult = 0.5
            ent.repair = ent.repair*0.95
        end
    end
    
    return mult
end

//Do damage to an entity
function STDamage( self, ent, dmg, dmgtype )
	if(not table.HasValue(candamage,ent:GetClass()) ) then return end
    
    if(ent.Core and ent.Core:IsValid() and table.HasValue(ent.Core.Ents,ent)) then
        if(self.Core == ent.Core) then return false end
        if(self.Core.driverteam == ent.Core.driverteam and cvar_ff:GetBool()==false) then return false end
        //if(ent.Core.driverteam==-1) then return false end
        
        ent.Core.hp = ent.Core.hp - dmg*CalcWeakness( ent, dmgtype )
        if( ent.Core.hp<=0 ) then 
            ent.Core:DoDeath( self.Core )
        end
    else
        ent.Core = NULL
        if( !ent.hp ) then
            ent.maxhp = CalcHealth( ent )
            ent.hp = ent.maxhp - dmg*CalcWeakness( ent, dmgtype )
            if( ent.hp<=0 ) then ent:Remove() end
        else
            ent.hp = ent.hp - dmg*CalcWeakness( ent, dmgtype )
            if( ent.hp<=0 ) then ent:Remove() end
        end
    end
    return true
end

//Does damage to props and damages a core only once per explosion, in a radius with falloff beginning at min and ending at max
function STAreaDamage( self, damage, dmgtype, pos, min, max )
    if(max<=0) then return end
    
    local find = ents.FindInSphere( pos, max )
    local dmgents = {}
    local count = 0
    for n,ent in pairs(find) do
        if(table.HasValue(candamage,ent:GetClass())) then
            count = count+1
            table.insert(dmgents,ent)
        end
    end
    
    for n,ent in pairs(dmgents) do
        local dmg = damage*RangeScale((ent:GetPos()-pos):Length(),min,max,true)
        STDamage(self,ent,dmg/count,dmgtype)
    end
end